package com.neuedu.it.newidea.config;

import com.neuedu.it.newidea.tools.SqlExecutionService;
import com.neuedu.it.newidea.tools.AISearchToolService;
import io.modelcontextprotocol.client.McpSyncClient;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiEmbeddingModel;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;
/*
各组可发挥功能幼分），例如:评论功能：AI自动审核评论
* */
@Configuration
public class AiConfig {
    @Autowired
    private OpenAiEmbeddingModel embeddingModel;

    @Bean
    public VectorStore vectorStore() {return SimpleVectorStore.builder(embeddingModel).build();}

    @Bean
    public ChatMemory chatMemory() {
        ChatMemory chatMemory  = MessageWindowChatMemory.builder()
                .maxMessages(5)
                .build();
        return chatMemory;
    }
    @Bean
    public ChatClient chatClientTxt(OpenAiChatModel openAiChatModel, ChatMemory chatMemory) {
        return ChatClient.builder(openAiChatModel)
                .defaultSystem("你是一个小说家，根据作者的意图，编写小说。字数限制在1000字内.")
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(chatMemory).build()
                        ,new SimpleLoggerAdvisor()
                )
                .build();
    }

    @Bean
    public ChatClient chatClientPoem(OpenAiChatModel openAiChatModel, ChatMemory chatMemory) {
        return ChatClient.builder(openAiChatModel)
                .defaultSystem("你是一个诗人，根据用户的意图，编写诗词或诗歌。字数限制在1000字内.")
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(chatMemory).build()
                        ,new SimpleLoggerAdvisor()
                )
                .build();
    }

    @Bean
    public ChatClient chatClientHappy(OpenAiChatModel openAiChatModel, ChatMemory chatMemory) {
        return ChatClient.builder(openAiChatModel)
                .defaultSystem("你是一个有创意的祝福语语言学家，根据作者的主题，编写祝福语，有趣得当有创意。字数限制在200字内.")
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(chatMemory).build()
                        ,new SimpleLoggerAdvisor()
                )
                .build();
    }
    @Bean
    public ChatClient chatClientSearch(OpenAiChatModel openAiChatModel, ChatMemory chatMemory, AISearchToolService aiSearchToolService) {
        return ChatClient.builder(openAiChatModel)
                .defaultSystem("""
                    你是一个智能数据库查询助手。根据用户的提问，你可以自动调用工具来查询数据库中的创作记录或用户信息。
                    当用户询问关于作品（Creation）时，调用 `searchCreations` 工具。
                    当用户询问关于特定用户（User）的信息（昵称、登录名、邮箱、积分）时，调用 `searchUsers` 工具。
                    当用户询问积分最高的个人信息时，调用 `findUserWithHighestScore` 工具。
                    请尽量从工具函数的结果中提取信息来回答用户，并以简洁明了的方式呈现。
                    如果工具调用失败或没有找到数据，请礼貌地告知用户。
                    工具函数的返回值会被自动插入到聊天流中，你需要基于这些信息进行回复。
                    """)
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(chatMemory).build()
                        ,new SimpleLoggerAdvisor()
                )
                .defaultTools(aiSearchToolService)
                .build();
    }
    @Autowired
    private List<McpSyncClient> mcpSyncClients;
    @Autowired
    private SqlExecutionService sqlExecutionService;
//    @Autowired
//    private CreationSqlTool creationSqlTool;
    @Bean
    public ChatClient asistantClient(OpenAiChatModel openAiChatModel, ChatMemory chatMemory, AISearchToolService aiSearchToolService) {
        return ChatClient.builder(openAiChatModel)
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(chatMemory).build()
                        ,new SimpleLoggerAdvisor()
                )
                .defaultSystem("一、核心职责\n" +
                        "仅操作已知表结构（通过 getTableStructureInfo () 获取）的表，包括 creations（创作表）、users（用户表）、cgys（分类表）等，禁止操作未授权表 / 字段。\n" +
                        "仅向 users 表中存在的用户发送邮件，接收人需匹配表中合法联系方式，禁止向非系统用户发邮件。\n" +
                        "此外，严禁修改score=-1用户的在数据库中任何数据，包括他user表中的增删改查以及creation表中的增删改查等，因为他是管理员\n"+
                        "二、数据库操作规则\n" +
                        "（一）操作前必须确认的场景\n" +
                        "执行 INSERT/UPDATE/DELETE 等写操作（用 executeUpdateSql），必须确认。\n" +
                        "执行 SELECT 读操作，若涉及 users 表敏感信息（密码、联系方式等），必须确认；仅查公开数据（如 cgys 表分类名、creations 表公开作品信息）可直接执行。\n" +
                        "多表联合查询（尤其 creations、users、cgys 关联），若结果含用户敏感信息，必须确认。\n" +
                        "（二）确认需包含的信息\n" +
                        "明确操作类型（如 “插入数据”“更新用户信息”“删除作品记录”“查询用户关联作品”）。\n" +
                        "列出涉及的表名、字段名（尤其是敏感字段）。\n" +
                        "写操作：提供拟执行的完整 SQL（敏感值用 *** 替换）；读操作：说明查询范围和返回数据结构。\n" +
                        "示例：“请确认执行：更新 users 表 u_id=123 的 u_email 字段，SQL：UPDATE users SET u_email='new@example.com' WHERE u_id=123，将用 executeUpdateSql 执行。”\n" +
                        "（三）SQL 编写规范\n" +
                        "三表联合查询必须用指定关联关系：\n" +
                        "creations 与 users：creations.s_userid = users.u_id\n" +
                        "creations 与 cgys：creations.s_cgy = cgys.cgy_id\n" +
                        "禁止用未明确的关联字段。\n" +
                        "写操作（除 INSERT）必须带 WHERE 条件，禁止无条件 UPDATE/DELETE（如 DELETE FROM users），防止全表数据丢失。\n" +
                        "查敏感信息时，仅选必要字段，排除冗余敏感数据（如不返回 u_password），禁止用 SELECT *，需明确指定字段。\n" +
                        "读操作必须用 executeQuerySql，写操作必须用 executeUpdateSql，确认后才可调用工具。\n" +
                        "三、用户邮件通知规则\n" +
                        "（一）发送前必须确认的信息\n" +
                        "明确接收人（用 users 表 u_id 或 u_name 确认，如 “向 u_id=456（用户名：xxx）发邮件”）。\n" +
                        "说明邮件主题、核心内容（如 “主题：作品审核通知；内容：您的作品《xxx》已通过审核”）。\n" +
                        "提示 “邮件发送后无法撤回，确认是否执行”。\n" +
                        "（二）禁止发送的情况\n" +
                        "无法在 users 表匹配到接收人，提示 “未找到对应用户，无法发送”。\n" +
                        "邮件含违规内容（恶意链接、虚假信息、隐私内容），禁止发送并提醒规范内容。\n" +
                        "（三）邮件内容规范\n" +
                        "内容需与系统业务相关（作品审核、账户变更、分类调整等），禁止无关内容。\n" +
                        "可包含业务数据（作品 ID、分类名等），禁止泄露用户敏感信息（密码、未公开联系方式等）。\n" +
                        "末尾标注系统标识（如 “——XX 系统管理员通知”），方便用户识别来源。\n" +
                        "四、操作优先级与容错\n" +
                        "优先级：读操作（查）> 写操作（改），写操作需更严格确认；批量操作（批量发邮件、批量更新）需说明影响范围（如 “向 10 名用户发邮件，ID：123、456...”），并确认。\n" +
                        "容错：\n" +
                        "操作失败（数据库连接错、邮件服务器异常），及时告知原因，询问是否重新执行（重新执行前需再次确认）。\n" +
                        "操作后发现数据异常（如误更新），立即提示用户，提供恢复方案（如备份恢复建议），但不可擅自恢复（需用户确认后配合）。\n" +
                        "五、必须遵守的底线原则\n" +
                        "确认前置：数据修改（写）、敏感数据查询、用户邮件通知，必须经用户明确确认，无确认绝对不执行。\n" +
                        "最小权限：数据库操作仅获取必要数据；邮件仅包含必要业务信息，不冗余暴露数据。\n" +
                        "可追溯：操作后向用户反馈结果（如 “SQL 执行成功，影响 1 条记录”“邮件已发送至 xxx@example.com”）。")
                .defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpSyncClients))
                .defaultTools(sqlExecutionService)
                .build();
    }
    /**
     * 提供数据库表结构信息给AI，帮助其生成正确的SQL
     */
    private String getTableStructureInfo() {
        return "1. 分类表(cgys): " +
                "   - cgy_id: 分类ID(主键)" +
                "   - cgy_name: 分类名称\n" +
                "2. 创作表(creations): " +
                "   - s_id: 创作ID(主键)" +
                "   - s_title: 标题" +
                "   - s_content: 内容" +
                "   - s_img: 图片" +
                "   - s_click: 点击量" +
                "   - s_userid: 用户ID(外键，关联users.u_id)" +
                "   - s_cgy: 分类ID(外键，关联cgys.cgy_id)" +
                "   - s_keyword: 关键词" +
                "   - s_createtime: 创建时间\n" +
                "3. 用户表(users): " +
                "   - u_id: 用户ID(主键)" +
                "   - u_nickname: 昵称" +
                "   - u_loginname: 登录名" +
                "   - u_loginpwd: 登录密码" +
                "   - u_email: 邮箱" +
                "   - u_score: 积分";
    }
    @Bean
    public ChatClient chatWithSchoolActivitiesClient(OpenAiChatModel model, ChatMemory chatMemory) {
        return ChatClient.builder(model)
                .defaultSystem("""
                        你是鸟哥，是一个知识库管理助手。请以博览群书的专家的身份和语气回答问题。\\n
                        请尽可能根据你提供的信息进行回答，尽量不要使用你自己的预设知识。\\n
                        如果提供的信息中没有答案，你将根据你的预设知识回答。
                    """)
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(chatMemory).build(),
                        new SimpleLoggerAdvisor()
                )
                .build();
    }
}
